-module(vector).
-export([normalize/1,
         strength/1,
         dot/2,
         cross/2,
         rest/2,
         sum/2,
         mult/2]).

%% @type vec3() = {vec3, float(), float(), float()}.

%% @spec normalize(Vector::vec3()) -> VectorNormalizado::vec3()
%% @doc Normaliza un vector
normalize(V = {vec3, X, Y, Z}) ->
    W = poly:length(V),
    case W of
        0.0 ->
            {vec3, 0, 0, 0};
        L ->
            {vec3, X / L, Y / L, Z / L}
    end.

%% @spec strength(Vector::vec3()) -> Longitud::float()
%% @doc Calcula la longitud de un vector
strength({vec3, X, Y, Z}) ->
    math:sqrt(X*X + Y*Y + Z*Z).

%% @spec dot(Vector1::vec3(), Vector2::vec3()) -> Escalar::float()
%% @doc Calcula el producto punto de dos vectores.
dot({vec3, X1, Y1, Z1}, {vec3, X2, Y2, Z2}) ->
    (X1*X2 + Y1*Y2 + Z1*Z2).

%% @spec cross(Vector1::vec3(), Vector2::vec3()) -> VectorCruz::vec3()
%% @doc Producto cruz de dos vectores
cross({vec3, Bx, By, Bz}, {vec3, Cx, Cy, Cz}) ->
    {vec3, (By * Cz) - (Bz * Cy), (Bz * Cx) - (Bx * Cz), (Bx * Cy) - (By * Cx)}.

%% @spec rest(A::vec3(), B::vec3()) -> Resultado::vec3()
%% @doc Resta el vector A - B
rest(_A = {vec3, X1, Y1, Z1}, _B = {vec3, X2, Y2, Z2}) ->
    {vec3, X1 - X2, Y1 - Y2, Z1 - Z2}.

%% @spec sum(A::vec3(), B::vec3()) -> Resultado::vec3()
%% @doc Suma el vector A + B
sum({vec3, X1, Y1, Z1}, {vec3, X2, Y2, Z2}) ->
    {vec3, X1 + X2, Y1 + Y2, Z1 + Z2}.

%% @spec mult(A::vec3(), T::float()) -> Resultado::vec3()
%% @doc Multiplica el vector A por un escalar T
mult({vec3, X, Y, Z}, T) ->
    {vec3, X * T, Y * T, Z * T}.
